﻿using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using PropertyMetadata = System.Windows.PropertyMetadata;

namespace YY.Admin.Core.Behavior
{
    public class TreeViewItemClickBehavior
    {
        // ICommand attached property
        public static readonly DependencyProperty CommandProperty =
            DependencyProperty.RegisterAttached(
                "Command",
                typeof(ICommand),
                typeof(TreeViewItemClickBehavior),
                new PropertyMetadata(null, OnCommandChanged));

        public static void SetCommand(DependencyObject obj, ICommand value) => obj.SetValue(CommandProperty, value);
        public static ICommand GetCommand(DependencyObject obj) => (ICommand)obj.GetValue(CommandProperty);

        // CommandParameter attached property
        public static readonly DependencyProperty CommandParameterProperty =
            DependencyProperty.RegisterAttached(
                "CommandParameter",
                typeof(object),
                typeof(TreeViewItemClickBehavior),
                new PropertyMetadata(null));

        public static void SetCommandParameter(DependencyObject obj, object value) => obj.SetValue(CommandParameterProperty, value);
        public static object GetCommandParameter(DependencyObject obj) => obj.GetValue(CommandParameterProperty);

        private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is TreeViewItem tvi)
            {
                if (e.NewValue != null && e.OldValue == null)
                {
                    tvi.PreviewMouseLeftButtonUp += OnTreeViewItemMouseLeftButtonUp;
                    // 监听 TreeViewItem 展开事件Expanded
                    tvi.Expanded += OnTreeViewItemExpanded;
                }
                else if (e.NewValue == null && e.OldValue != null)
                {
                    tvi.PreviewMouseLeftButtonUp -= OnTreeViewItemMouseLeftButtonUp;
                    tvi.Expanded -= OnTreeViewItemExpanded;
                }
            }
            else
            {
                // 如果Style被应用到容器等，也可能不是TreeViewItem，延迟订阅由容器化过程处理
                // 一般我们只使用在 TreeViewItem 上设置
            }
        }

        private static void OnTreeViewItemMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            // 忽略点击展开按钮
            if (e.OriginalSource is DependencyObject dep)
            {
                if (FindAncestor<ToggleButton>(dep) != null) return;

                // 找到真正的 TreeViewItem
                var tvi = FindAncestor<TreeViewItem>(dep);
                if (tvi == null) return;

                var cmd = GetCommand(tvi);
                var param = GetCommandParameter(tvi) ?? tvi.DataContext;

                // 检查是否有子项
                bool hasChildren = tvi.HasItems;

                // 如果有子项，则切换展开状态
                if (hasChildren)
                {
                    bool IsExpanded = !tvi.IsExpanded;
                    tvi.IsExpanded = IsExpanded;

                    // 展开
                    //if (IsExpanded)
                    //{
                    //    // 关闭同级其它节点
                    //    CollapseSiblings(tvi);
                    //}

                    e.Handled = true;
                    return;
                }

                if (cmd != null && cmd.CanExecute(param))
                {
                    cmd.Execute(param);
                    e.Handled = true;
                }
            }
        }

        private static void OnTreeViewItemExpanded(object sender, RoutedEventArgs e)
        {
            if (sender is TreeViewItem tvi)
            {
                // 防止事件冒泡重复执行
                if (e.OriginalSource != tvi)
                    return;

                CollapseSiblings(tvi);
            }
        }


        /// <summary>
        /// 折叠同级其它 TreeViewItem
        /// </summary>
        private static void CollapseSiblings(TreeViewItem currentItem)
        {
            ItemsControl parent = ItemsControl.ItemsControlFromItemContainer(currentItem);
            if (parent == null) return;

            foreach (var item in parent.Items)
            {
                var container = parent.ItemContainerGenerator.ContainerFromItem(item) as TreeViewItem;
                if (container != null && container != currentItem)
                {
                    container.IsExpanded = false;
                }
            }
        }

        // 查找祖先辅助方法
        private static T FindAncestor<T>(DependencyObject current) where T : DependencyObject
        {
            while (current != null)
            {
                if (current is T t) return t;
                current = VisualTreeHelper.GetParent(current);
            }
            return null;
        }
    }
}
